package com.hb.common.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.json.JSONUtil;
import com.hb.common.dto.Database;
import com.hb.common.dto.DatabaseDto;
import com.hb.common.dto.DbBackupTask;
import com.hb.common.service.DatabaseService;
import com.hb.common.service.DbBackupFileService;
import com.hb.common.service.DbBackupTaskService;
import com.hb.common.util.CommonUtil;
import com.hb.common.util.PathPermissions;
import com.hb.common.util.PropertiesUtil;
import com.hb.common.util.Result;
import jakarta.annotation.Resource;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.Objects;

/**
 * 备份任务
 */
@Service
public class DatabaseServiceImpl implements DatabaseService {

    @Resource
    private PropertiesUtil propertiesUtil;
    @Resource
    private DbBackupFileService dbBackupFileService;
    @Resource
    private PathPermissions pathPermissions;
    @Resource
    private ApplicationContext applicationContext;

    /**
     * 获取数据库列表及其他信息
     */
    @Override
    public Result<List<DatabaseDto>> selectDtoList() {
        // 获取配置文件里的数据库列表
        String dbList = propertiesUtil.getValue("dbList");
        List<DatabaseDto> databaseDtoList = BeanUtil.copyToList(JSONUtil.parseArray(dbList), DatabaseDto.class);
        for (DatabaseDto databaseDto : databaseDtoList) {
            try {
                // 备份文件数量
                Database database = BeanUtil.copyProperties(databaseDto, Database.class);
                Integer count = dbBackupFileService.selectCount(database).getData();
                databaseDto.setFileCount(count);

                // 定时备份周期
                DbBackupTask dbBackupTask = applicationContext.getBean(DbBackupTaskService.class).selectById(databaseDto.getId()).getData();
                if (Objects.nonNull(dbBackupTask)) {
                    databaseDto.setCron(dbBackupTask.getCron());
                }
            } catch (Exception e) {
                databaseDto.setFileCount(0);
            }
        }
        return Result.success(databaseDtoList);
    }

    /**
     * 获取数据库选择列表
     */
    @Override
    public Result<List<DatabaseDto>> selectSelectionList(String dbType) {
        String dbList = propertiesUtil.getValue("dbList");
        List<DatabaseDto> databaseDtoList = BeanUtil.copyToList(JSONUtil.parseArray(dbList), DatabaseDto.class);
        List<DatabaseDto> resultList = databaseDtoList.stream().filter(x -> x.getDbType().equalsIgnoreCase(dbType)).toList();
        return Result.success(resultList);
    }

    /**
     * 获取数据库列表
     */
    @Override
    public Result<List<Database>> selectList() {
        // 获取配置文件里的数据库列表
        String dbList = propertiesUtil.getValue("dbList");
        List<Database> databaseList = BeanUtil.copyToList(JSONUtil.parseArray(dbList), Database.class);
        return Result.success(databaseList);
    }

    /**
     * 保存或更新数据库
     */
    @Override
    public Result<Boolean> insertOrUpdate(Database database) {
        // 获取数据库列表
        List<Database> databaseList = this.selectList().getData();

        // 根据id判断是否存在
        int index = databaseList.indexOf(database);
        if (index >= 0) {
            // 修改
            String password = databaseList.get(index).getPassword();
            if (!Objects.equals(password, database.getPassword())) {
                database.setPassword(CommonUtil.encryptPassword(database.getPassword()));
            }
            databaseList.removeIf(x -> Objects.equals(x.getId(), database.getId()));
            // 更新
            databaseList.add(index, database);
        } else {
            // 添加
            database.setPassword(CommonUtil.encryptPassword(database.getPassword()));
            database.setId(IdUtil.fastUUID().hashCode());
            databaseList.add(database);
        }
        propertiesUtil.setValue("dbList", JSONUtil.toJsonStr(databaseList));

        // 生成备份目录
        String dbBackupPath = pathPermissions.getDbBackupPath(database);
        CommonUtil.validateOrCreateDirectory(dbBackupPath);

        return Result.success();
    }

    /**
     * 根据id获取数据库
     */
    @Override
    public Result<Database> selectById(Integer id) {
        List<Database> databaseList = this.selectList().getData();
        Database database = databaseList.stream().filter(x -> Objects.equals(x.getId(), id)).findFirst().orElse(null);
        if (database != null) {
            return Result.success(database);
        }
        return Result.fail("数据库不存在");
    }

    /**
     * 根据id获取数据库（解密密码）
     */
    @Override
    public Result<Database> selectDecryptPasswordById(Integer id) {
        List<Database> databaseList = this.selectList().getData();
        Database database = databaseList.stream().filter(x -> Objects.equals(x.getId(), id)).findFirst().orElse(null);
        if (database != null) {
            database.setPassword(CommonUtil.decryptPassword(database.getPassword()));
            return Result.success(database);
        }
        return Result.fail("数据库不存在");
    }

    /**
     * 删除数据库
     */
    @Override
    public Result<Boolean> delete(List<Integer> ids) {
        for (Integer id : ids) {
            List<Database> databaseList = this.selectList().getData();
            databaseList.removeIf(x -> Objects.equals(x.getId(), id));
            propertiesUtil.setValue("dbList", JSONUtil.toJsonStr(databaseList));
        }
        return Result.success();
    }

    /**
     * 更新数据库备份文件数量
     */
    @Override
    public Result<Boolean> updateFileCount(Integer id, Integer maxFileNum) {
        Database database = this.selectById(id).getData();
        if (database != null) {
            database.setMaxFileNum(maxFileNum);
            return this.insertOrUpdate(database);
        }
        return Result.fail("数据库不存在");
    }

}
